package com.wordsay.core;

import java.io.File;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.lionsoul.jcseg.core.IWord;

import com.wordsay.analyer.Analyer;
import com.wordsay.analyer.impl.GroupAnalyer;
import com.wordsay.analyer.impl.JcsegAnalyer;
import com.wordsay.analyer.impl.OverallAnalyer;
import com.wordsay.analyer.impl.PersonSimilarAnayler;
import com.wordsay.analyer.impl.PersonalityAnalyer;
import com.wordsay.common.Constant;
import com.wordsay.context.Context;
import com.wordsay.context.Resource;
import com.wordsay.entity.AnalystResult;
import com.wordsay.entity.Dialog;
import com.wordsay.entity.GroupDialog;
import com.wordsay.entity.OverallAnalystResult;
import com.wordsay.entity.PDialogAnalystResult;
import com.wordsay.entity.PersonDialog;
import com.wordsay.entity.PersonSimilarResult;
import com.wordsay.entity.Talk;
import com.wordsay.parser.ChatParser;
import com.wordsay.parser.impl.FxChatParserProxy;

public class Wordsay {

	private static Logger log = LogManager.getLogger(Wordsay.class.getName());  
	
	public Wordsay(){
		
		log.info("init the wordsay start ...");
		Context.getInstance();
	}
	
	/**
	 * analyst the chat record
	 * @param chatFilePath
	 * @param chatApp
	 * @return
	 */
	public boolean parseChatRecord(String chatFilePath,String chatApp)  throws Exception {
		
		if(chatApp == null || chatApp.trim().equals("")){
			throw new Exception("未指定chatApp类型");
		}
		
		ChatParser chatParser = null;
		//read and parse the chat record into Resource context
		if(chatApp.trim().equalsIgnoreCase(Constant.CHAT_APP_FEIXIN)){
			
		    chatParser = new FxChatParserProxy();
		    
		}
		
		long startAnalystFile = System.currentTimeMillis();
		//else{} //prepare for other chat App 
		if(!this.analystFile(chatParser, chatFilePath)){
			log.warn("分析数据文件失败");
			return false;
		}
	
		long startFenci = System.currentTimeMillis();
		//analyst the chat resources into analyst result, using the analyer
		Resource resource = Context.getInstance().getResource();
		Analyer analyer = new JcsegAnalyer();
		log.info("analyst person dialog");
		this.jcsegAnalyTalks(resource.getPersonDialogs());
		long afenEnd = System.currentTimeMillis();
		log.info("analyst group dialog");
		this.jcsegAnalyTalks(resource.getGroupDialogs());
		long bfenEnd = System.currentTimeMillis();

		log.info("analyst discussion dialog");
		this.jcsegAnalyTalks(resource.getDiscussionDialogs());
		long cfenEnd = System.currentTimeMillis();

		System.out.println("解析聊天记录用时："+(startFenci-startAnalystFile)/1000+"s  分词个人聊天："+(afenEnd-startFenci)/1000+"s  分词群聊天:"+(bfenEnd-afenEnd)/1000+"s 分词讨论组聊天:"+(cfenEnd-bfenEnd)/1000+"s");
		
		return true;
	}
	
	/**
	 * execute the overall analyst based on the chat record analysis
	 * @return
	 */
	public AnalystResult executeOverallAnalyst() throws Exception{
		
		OverallAnalystResult analystResult;
		
		Resource resource = Context.getInstance().getResource();
		Analyer analyer = new OverallAnalyer();
		
		analystResult = (OverallAnalystResult)analyer.execute(resource);
		return analystResult;
	}
	
	/**
	 * execute the persions analyst
	 * @throws Exception
	 */
	public void executePersonsAnalyst() throws Exception{
		
		Resource resource = Context.getInstance().getResource();
		Iterator<PersonDialog> dialogs = resource.getPersonDialogs().values().iterator();
		
		PersonalityAnalyer analyer = new PersonalityAnalyer();
		while(dialogs.hasNext()){
			
			PersonDialog dialog = dialogs.next();
			AnalystResult result = (AnalystResult)analyer.execute(dialog);
			if(result == null){
				continue;
			}
			dialog.setAnalystResult(result);	
			System.out.println("\n和"+dialog.getOtherPeople().getName()+"的聊天记录分析结果------------------------------------");
			result.printResult();
		}
	}
	

	/**
	 * execute the persions analyst
	 * @throws Exception
	 */
	public void executeGroupsAnalyst() throws Exception{
		
		Resource resource = Context.getInstance().getResource();
		Iterator<GroupDialog> dialogs = resource.getGroupDialogs().values().iterator();
		
		GroupAnalyer analyer = new GroupAnalyer();
		while(dialogs.hasNext()){
			
			GroupDialog dialog = dialogs.next();
			AnalystResult result = (AnalystResult)analyer.execute(dialog);
			if(result == null){
				continue;
			}
			dialog.setAnalystResult(result);	
			System.out.println("\n群: "+dialog.getGroup().getName()+" 的聊天记录分析结果------------------------------------");
			result.printResult();
		}
	}
	
	
	/**
	 * execute the persions analyst
	 * @throws Exception
	 */
	public void executeDiscussionsAnalyst() throws Exception{
		
		Resource resource = Context.getInstance().getResource();
		Iterator<GroupDialog> dialogs = resource.getDiscussionDialogs().values().iterator();
		
		GroupAnalyer analyer = new GroupAnalyer();
		while(dialogs.hasNext()){
			
			GroupDialog dialog = dialogs.next();
			AnalystResult result = (AnalystResult)analyer.execute(dialog);
			if(result == null){
				continue;
			}
			dialog.setAnalystResult(result);	
			System.out.println("\n讨论组: "+dialog.getGroup().getName()+" 的聊天记录分析结果------------------------------------");
			result.printResult();
		}
	}
	
	/**
	 * execute the person similar anlayst
	 * @throws Exception
	 */
	public void executePersonSimilarAnalyst() throws Exception {
		
		Resource resource = Context.getInstance().getResource();
		PersonSimilarAnayler analyer = new PersonSimilarAnayler();
		Map<String,String> similarPersonRange = Context.getInstance().getSimilarPersonRange();
		
		List<PersonDialog> dialogs = new ArrayList<PersonDialog>();
		Iterator<PersonDialog> dialogIterator = resource.getPersonDialogs().values().iterator();
		while(dialogIterator.hasNext()){
			
			PersonDialog dialog = dialogIterator.next();
			
			if(similarPersonRange.size() > 0 && similarPersonRange.containsKey(dialog.getOtherPeople().getName())){
				dialogs.add(dialog);
			}
		}
		
		List<PersonSimilarResult> results  = (List<PersonSimilarResult>)analyer.execute(dialogs);
		resource.setPersonSimilareResult(results);
	    System.out.println("个人相似度分析结果---------------------------------------------");
	    for(PersonSimilarResult result : results){result.printResult();};
	}
	
	/**
	 * analyst the file
	 * @param parser
	 * @param chatFilePath
	 * @return
	 * @throws Exception
	 */
	private boolean analystFile(ChatParser parser,String chatFilePath) throws Exception{
		
		 File file = new File(chatFilePath);
		 if(!file.exists()){
			 log.warn("chat file path not existed : "+chatFilePath);
			 return false;
		 }
		 
		 log.info("analyst file ["+chatFilePath+"] -> directory is "+file.isDirectory());
		 if(file.isDirectory()){
			 
			 //String[] subFiles = file.list();
			 File[] subFiles = file.listFiles();
			 log.info("loop analsyt file ["+chatFilePath+"] 's sub files");

			 for(int i = 0; i < subFiles.length; i++){
				 
				 File subFile = subFiles[i];
				 if(subFile.getName().substring(0,1).equals(".")){
					 continue;
				 }
				 
				 this.analystFile(parser, subFile.getCanonicalPath());
			 }
			 
		 }else{
			 
			 long start = System.currentTimeMillis();
			 log.info("analyst file ["+chatFilePath+"] start");
			 Resource resource = Context.getInstance().getResource();
			 Object obj = parser.parse(chatFilePath);
			 
			 if(obj instanceof PersonDialog){
				 
				 PersonDialog dialog = (PersonDialog)obj;
				 resource.getPersonDialogs().put(dialog.getOtherPeople().getName(), dialog);
				 
			 }else if(obj instanceof GroupDialog){
				 
				 GroupDialog dialog = (GroupDialog)obj;
				 
				 if(dialog.getGroup().isDiscussion()) {
					 
					 resource.getDiscussionDialogs().put(dialog.getGroup().getName(), dialog);
				 
				 }else {
					 
                     resource.getGroupDialogs().put(dialog.getGroup().getName(), dialog);
				 }				 				 
			 }
			 log.info("analyst file ["+chatFilePath+"] end, spent: "+(System.currentTimeMillis() - start)+"ms");
		 }
		 
		 
		 return true;
	}
	
	/**
	 * 进行中文分词
	 * @param dialogs
	 */
	private void jcsegAnalyTalks(Map<String,? extends Dialog> dialogs) throws Exception{
				
		Analyer analyer = new JcsegAnalyer();
		Iterator iterator = dialogs.values().iterator();
		while(iterator.hasNext()){
			
			Dialog dialog = (Dialog)iterator.next();
			List<Talk> talks = dialog.getTalks();
			
			for(Talk talk : talks){
				
				List<IWord> iwords= (List<IWord>)analyer.execute(talk.getMessage());
				talk.setIwords(iwords);
				for(int i = 0; i < iwords.size();i++){
					
					
					System.out.println(iwords.get(i).getValue()+"  -  type:"+iwords.get(i).getType()
							+"  -  position:"+iwords.get(i).getPosition()+"  -  length:"+iwords.get(i).getLength()+"   -  frequency:"+iwords.get(i).getFrequency());
				}
			}
		}
		
	}
}
